package com.cwvs.controller.api;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cwvs.helper.PingPlusPlus;
import com.cwvs.models.ResultInfo;
import com.cwvs.services.AppNeedOrderService;
import com.cwvs.services.AppOrderService;
import com.cwvs.services.AppPayService;
import com.cwvs.services.AppUserService;
import com.cwvs.utils.AppConstants;
import com.cwvs.utils.CommonUtils;
import com.pingplusplus.exception.APIConnectionException;
import com.pingplusplus.exception.APIException;
import com.pingplusplus.exception.AuthenticationException;
import com.pingplusplus.exception.InvalidRequestException;
import com.pingplusplus.model.Charge;
import com.pingplusplus.model.Notify;

/**
 * 
 * 支付Controller
 */
@RequestMapping("/api")
@Controller
public class PayController {
	@Resource
	private AppUserService appUserService;
	@Resource
	private AppOrderService appOrderService;
	@Resource
	private PingPlusPlus pingPlusPlus;
	@Resource
	private AppPayService appPayService;
	@Resource
	private AppNeedOrderService appNeedOrderService;
	private static Logger logger = Logger.getLogger(PayController.class
			.getName());

	/**
	 * 支付请求发起
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@RequestMapping("/pay")
	public @ResponseBody
	ResultInfo pay(HttpServletRequest request, HttpServletResponse response) {
		ResultInfo res = new ResultInfo();
		Map<String, Object> map = new HashMap<String, Object>();
		Enumeration paramNames = request.getParameterNames();
		while (paramNames.hasMoreElements()) {
			String paramName = (String) paramNames.nextElement();
			String[] paramValues = request.getParameterValues(paramName);
			if (paramValues.length == 1) {
				String paramValue = paramValues[0];
				if (paramValue.length() != 0) {
					map.put(paramName.toUpperCase(), paramValue);
				}
			}
		}
		String token = request.getParameter("token");
		if (StringUtils.isBlank(token)) {
			res.setMessage("无效的登录信息");
			return res;
		}
		res = appUserService.getUserInfo(token);
		if (!res.isSuccess()) {
			return res;
		}
		Map<String, Object> orderType = appOrderService
				.getOrderTypeByCode(MapUtils.getString(map, "ORDER_TYPE"));
		if (null == orderType) {
			res.setMessage("无效的订单类型");
			res.setResCode("0");
			res.setResult(null);
			res.setSuccess(false);
			return res;
		}
		if (StringUtils.isBlank(MapUtils.getString(map, "PAY_TYPE"))) {
			res.setMessage("无效的支付类型");
			res.setResCode("0");
			res.setResult(null);
			res.setSuccess(false);
			return res;
		}
		String uid = MapUtils.getString(
				((Map<String, Object>) res.getResult()), "USER_ID");
		String id = MapUtils.getString(map, "ID");
		Map<String, Object> order = appOrderService.orderInfoById(uid, id);
		if (null == order || order.isEmpty()) {
			res.setMessage("无效的订单");
			res.setSuccess(false);
			res.setResult(null);
			res.setResCode("0");
			return res;
		}
		if (MapUtils.getIntValue(order, "STATUS") != 3) {
			res.setMessage("该订单状态不允许支付");
			res.setSuccess(false);
			res.setResult(null);
			res.setResCode("0");
			return res;
		}
		// 获取客户端地址
		String client_ip = CommonUtils.getIpAddr(request);
		order.put("CLIENT_IP", client_ip);
		order.put("PAY_TYPE", MapUtils.getString(map, "PAY_TYPE"));
		Charge ch = pingPlusPlus.getCharge(order);
//		logger.info("#1#" + ch);
		if (null == ch) {
			res.setMessage("支付调用失败");
			res.setSuccess(false);
			res.setResult(null);
			res.setResCode("0");
			return res;
		}
		appOrderService.updateOrderCharge(MapUtils.getString(order, "ID"),
				ch.getId());
		res.setResult(ch);
		res.setSuccess(true);
		res.setMessage("支付调用成功");
		return res;
	}

	/**
	 * 需求支付请求发起
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@RequestMapping("/need_pay")
	public @ResponseBody
	ResultInfo needPay(HttpServletRequest request, HttpServletResponse response) {
		ResultInfo res = new ResultInfo();
		Map<String, Object> map = new HashMap<String, Object>();
		Enumeration paramNames = request.getParameterNames();
		while (paramNames.hasMoreElements()) {
			String paramName = (String) paramNames.nextElement();
			String[] paramValues = request.getParameterValues(paramName);
			if (paramValues.length == 1) {
				String paramValue = paramValues[0];
				if (paramValue.length() != 0) {
					map.put(paramName.toUpperCase(), paramValue);
				}
			}
		}
		String token = request.getParameter("token");
		if (StringUtils.isBlank(token)) {
			res.setMessage("无效的登录信息");
			return res;
		}
		res = appUserService.getUserInfo(token);
		if (!res.isSuccess()) {
			return res;
		}
		if (StringUtils.isBlank(MapUtils.getString(map, "PAY_TYPE"))) {
			res.setMessage("无效的支付类型");
			res.setResCode("0");
			res.setResult(null);
			res.setSuccess(false);
			return res;
		}
		String uid = MapUtils.getString(
				((Map<String, Object>) res.getResult()), "USER_ID");
//		String id = MapUtils.getString(map, "ID");
		Map<String, Object> order = appNeedOrderService.getInfoById(map);
		if (null == order || order.isEmpty()) {
			res.setMessage("无效的订单");
			res.setSuccess(false);
			res.setResult(null);
			res.setResCode("0");
			return res;
		}
		if(!StringUtils.equals(MapUtils.getString(order, "USER_ID"), uid) ){
			res.setMessage("无效的订单");
			res.setSuccess(false);
			res.setResult(null);
			res.setResCode("0");
			return res;
		}
		if (MapUtils.getIntValue(order, "STATUS") != 3) {
			res.setMessage("该订单状态不允许支付");
			res.setSuccess(false);
			res.setResult(null);
			res.setResCode("0");
			return res;
		}
		// 获取客户端地址
		String client_ip = CommonUtils.getIpAddr(request);
		order.put("CLIENT_IP", client_ip);
		order.put("PAY_TYPE", MapUtils.getString(map, "PAY_TYPE"));
		order.put("ORDER_NO", MapUtils.getString(order, "ID"));
		Charge ch = pingPlusPlus.getCharge(order);
//		logger.info("#1#" + ch);
		if (null == ch) {
			res.setMessage("支付调用失败");
			res.setSuccess(false);
			res.setResult(null);
			res.setResCode("0");
			return res;
		}
		appNeedOrderService.updateOrderCharge(MapUtils.getString(order, "ID"),
				ch.getId());
		res.setResult(ch);
		res.setSuccess(true);
		res.setMessage("支付调用成功");
		return res;
	}
	
	
	/**
	 * 支付成功回调通知
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping("/pay_type")
	public @ResponseBody
	List<String> getPayType(HttpServletRequest request,
			HttpServletResponse response) {
		return appPayService.getPay(request.getParameter("ORDER_TYPE"));
	}

	@RequestMapping("/pay_return")
	public @ResponseBody
	String payReturn(HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		request.setCharacterEncoding("UTF-8");
		// 读取异步通知数据
		BufferedReader reader = request.getReader();
		StringBuffer buffer = new StringBuffer();
		String string;
		while ((string = reader.readLine()) != null) {
			buffer.append(string);
		}
		reader.close();

		// 解析异步通知数据
		String notifyJson = new String(buffer);
		Object o = Notify.parseNotify(notifyJson);
		// 对异步通知做处理
		if (o instanceof Charge) {
			Charge charge = (Charge) o;
			// 插入回写日志
			appOrderService.insAppReturnPayLog(charge);
			String orderNo = charge.getOrderNo();
			if (StringUtils.isBlank(orderNo)) {
				return "fail";
			}
			Map<String, Object> orderInfo=null;
			if(orderNo.startsWith("TW")){
				 orderInfo = appOrderService
							.getOrderInfoByOrderNo(orderNo);
			}else{
				Map<String,Object> m=new HashMap<String,Object>();
				m.put("ID", orderNo);
				orderInfo =appNeedOrderService.getInfoById(m);
			}
			
			
			if (null == orderInfo || orderInfo.isEmpty()) {
				return "fail";
			}
			try {
				Charge re=pingPlusPlus.retrieveCharge(charge.getId());
				logger.info(re);
				if(!StringUtils.equals(re.getOrderNo(), orderNo)){
					return "fail";
				}
				if(!re.getPaid()){
					logger.info(re.getOrderNo()+"还未支付");
					return "fail";
				}
				
			} catch (AuthenticationException e) {
				logger.info(e.getMessage());
				return "fail";

			} catch (InvalidRequestException e) {
				logger.info(e.getMessage());
				return "fail";
			} catch (APIConnectionException e) {
				logger.info(e.getMessage());
				return "fail";
			} catch (APIException e) {
				logger.info(e.getMessage());
				return "fail";
			}
			// if (!StringUtils.equalsIgnoreCase(charge.getId(),
			// MapUtils.getString(orderInfo, "CHARGE_ID"))) {
			// return "fail";
			// }
			// 订单完成
			if (MapUtils.getIntValue(orderInfo, "STATUS") == AppConstants.STATUS_DONE) {
				return "success";
			}
			// 订单结束
			if (MapUtils.getIntValue(orderInfo, "STATUS") == AppConstants.STATUS_END) {
				return "success";
			}
			// 支付完成
			if (MapUtils.getIntValue(orderInfo, "STATUS") == AppConstants.STATUS_END_PAY) {
				return "success";
			}
			if (MapUtils.getIntValue(orderInfo, "STATUS") == 3) {
				boolean b=false;
				// 更新支付完成状态
				if(orderNo.startsWith("TW")){
					 b = appOrderService.updateStatus(
								MapUtils.getString(orderInfo, "ID"),
								AppConstants.STATUS_END_PAY,
								AppConstants.STATUS_END_PAY_NAME);
				}else{
					Map<String,Object> sta=new HashMap<String,Object>();
					sta.put("ID", orderNo);
					sta.put("STATUS", AppConstants.STATUS_END_PAY);
					sta.put("STATUS_NAME",AppConstants.STATUS_END_PAY_NAME);
					b=appNeedOrderService.cancelOrDone(sta);
				}

				if (!b) {
					return "fail";
				}
				if (!appOrderService.insAppPayLog(
						MapUtils.getString(orderInfo, "ID"), charge)) {
					return "fail";
				}
				return "success";
			}
			// 开发者在此处加入对支付异步通知的处理代码
			// 处理成功返回success
			return "fail";
		}
		// if (o instanceof Refund) {
		// Refund refund = (Refund) o;
		// // 开发者在此处加入对退款异步通知的处理代码
		// // 处理成功返回success
		// return "success";
		// }
		return "fail";
	}

}
